package com.huilan.config;

import com.alibaba.fastjson.JSONObject;
import com.huilan.util.JwtUtil;
import com.huilan.util.RedisUtil;
import com.huilan.util.ResponseResult;
import com.huilan.util.SpringUtil;
import io.jsonwebtoken.Claims;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;

/**
 * jwt权限认证
 * @author ghy
 */
public class JwtAuthenticationFilter extends BasicAuthenticationFilter {

    private RedisUtil redisUtil = null;

    public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws IOException, ServletException {
        //获取Token
        String token = request.getHeader(JwtUtil.AUTHORIZATION);

        //验证Token
        if(StringUtils.isEmpty(token)){
            responseStr(response,"未检测到携带token值，请检查！");
            return;
        }else{
            if (!JwtUtil.validate(token)) {
                responseStr(response,"token值无效！");
                return;
            }
        }
        Claims claims = JwtUtil.parseJWT(token);
        UsernamePasswordAuthenticationToken authenticationToken = null;
        String username = null;
        Integer userId;
        if(claims!=null){
            username = (String)claims.get(JwtUtil.USER_NAME);
            userId = (Integer)claims.get(JwtUtil.USER_ID);

            authenticationToken = new UsernamePasswordAuthenticationToken( username, null,new ArrayList<>());
        }else{
            responseStr(response,"token解析失败！");
            return;
        }

        if(redisUtil == null){
            redisUtil = SpringUtil.getBean(RedisUtil.class);
        }

        if(redisUtil.exists(username)){
            //以用户名为key,token为value  并设置过期时间
            if(!"admin".equals(username)){
                redisUtil.setExpireTime(username,JwtUtil.EXPIRATION_TIME);
            }

            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }else{
            responseStr(response,"用户身份信息已过期，请重新登录！");
            return;
        }

        super.doFilterInternal(request, response, filterChain);
    }

    private static void responseStr(ServletResponse response,String str) throws IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().println(JSONObject.toJSONString(ResponseResult.error(HttpStatus.UNAUTHORIZED.value(), str)));
    }
}
